package com.jingdianjichi.auth.application.controller;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Preconditions;
import com.jingdianjichi.auth.application.convert.AuthUserDTOConvert;
import com.jingdianjichi.auth.entity.AuthUserDTO;
import com.jingdianjichi.auth.domain.entity.AuthUserBO;
import com.jingdianjichi.auth.domain.service.AuthUseDomainService;
import com.jingdianjichi.auth.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * 用户controller
 */
@RestController
@RequestMapping("/user/")
@Slf4j
public class UserController {

    @Resource
    private AuthUseDomainService authUserDomainService;


    /**
     * 注册接口
     * @param authUserDTO
     * @return
     */
    @RequestMapping("register")
    public Result<Boolean> register(@RequestBody AuthUserDTO authUserDTO) {
        try {
            // 记录日志
            if (log.isInfoEnabled()) {
                log.info("UserController.register.dto:{}", JSON.toJSONString(authUserDTO));
            }
            // 校验输入参数
            Preconditions.checkArgument(StringUtils.isNotBlank(authUserDTO.getUserName()), "用户名称不能为空！");
            Preconditions.checkArgument(StringUtils.isNotBlank(authUserDTO.getEmail()), "邮件地址不能为空！");
            Preconditions.checkArgument(StringUtils.isNotBlank(authUserDTO.getPassword()), "密码不能为空！");

            // 转换DTO为BO
            AuthUserBO authUserBO = AuthUserDTOConvert.INSTANCE.convertDtoToBo(authUserDTO);
            // 调用领域服务实现注册服务
            Boolean result = authUserDomainService.register(authUserBO);
            return Result.ok(result);
        } catch (Exception e) {
            // 异常处理，记录错误日志并返回失败结果
            log.error("UserController.register.error：{}", e.getMessage(), e);
            return Result.fail("注册用户失败！");
        }
    }

    /**
     * 更新用户信息
     * @param authUserDTO
     * @return
     */
    @RequestMapping("update")
    public Result<Boolean> update(@RequestBody AuthUserDTO authUserDTO) {
        try {
            // 记录日志
            if (log.isInfoEnabled()) {
                log.info("UserController.update.dto:{}", JSON.toJSONString(authUserDTO));
            }

            // 转换DTO为BO
            AuthUserBO authUserBO = AuthUserDTOConvert.INSTANCE.convertDtoToBo(authUserDTO);
            // 调用领域服务实现注册服务
            Boolean result = authUserDomainService.update(authUserBO);
            return Result.ok(result);
        } catch (Exception e) {
            // 异常处理，记录错误日志并返回失败结果
            log.error("UserController.update.error：{}", e.getMessage(), e);
            return Result.fail("更新用户信息失败！");
        }
    }

    /**
     * 删除用户信息
     * @param authUserDTO
     * @return
     */
    @RequestMapping("delete")
    public Result<Boolean> delete(@RequestBody AuthUserDTO authUserDTO) {
        try {
            // 记录日志
            if (log.isInfoEnabled()) {
                log.info("UserController.delete.dto:{}", JSON.toJSONString(authUserDTO));
            }
            // 校验输入参数
            Preconditions.checkNotNull(authUserDTO.getId() , "用户ID不能为空！");

            // 转换DTO为BO
            AuthUserBO authUserBO = AuthUserDTOConvert.INSTANCE.convertDtoToBo(authUserDTO);
            // 调用领域服务实现删除服务
            Boolean result = authUserDomainService.delete(authUserBO);
            return Result.ok(result);
        } catch (Exception e) {
            // 异常处理，记录错误日志并返回失败结果
            log.error("UserController.delete.error：{}", e.getMessage(), e);
            return Result.fail("删除用户信息失败！");
        }
    }

    /**
     * 用户启用/禁用
     * @param authUserDTO
     * @return
     */
    @RequestMapping("changeStatus")
    public Result<Boolean> changeStatus(@RequestBody AuthUserDTO authUserDTO) {
        try {
            // 记录日志
            if (log.isInfoEnabled()) {
                log.info("UserController.changeStatus.dto:{}", JSON.toJSONString(authUserDTO));
            }
            // 校验输入参数
            Preconditions.checkNotNull(authUserDTO.getId() , "用户ID不能为空！");

            // 转换DTO为BO
            AuthUserBO authUserBO = AuthUserDTOConvert.INSTANCE.convertDtoToBo(authUserDTO);
            // 调用领域服务用户启用/禁用服务
            Boolean result = authUserDomainService.changeStatus(authUserBO);
            return Result.ok(result);
        } catch (Exception e) {
            // 异常处理，记录错误日志并返回失败结果
            log.error("UserController.changeStatus.error：{}", e.getMessage(), e);
            return Result.fail("用户启用/禁用失败！");
        }
    }

    /**
     * 个人信息查询
     * @param authUserDTO
     * @return
     */
    @RequestMapping("getUserInfo")
    public Result<AuthUserDTO> getUserInfo(@RequestBody AuthUserDTO authUserDTO) {
        try {
            // 记录日志
            if (log.isInfoEnabled()) {
                log.info("UserController.getUserInfo.dto:{}", JSON.toJSONString(authUserDTO));
            }
            // 校验输入参数
            Preconditions.checkArgument(StringUtils.isNotBlank(authUserDTO.getUserName()), "用户名称不能为空！");

            // 转换DTO为BO
            AuthUserBO authUserBO = AuthUserDTOConvert.INSTANCE.convertDtoToBo(authUserDTO);
            // 调用领域服务实现查询服务
            AuthUserBO result = authUserDomainService.getUserInfo(authUserBO);
            result.setPassword(null);
            // 转换BO为DTO
            AuthUserDTO userDTO = AuthUserDTOConvert.INSTANCE.convertBOToDTO(result);
            return Result.ok(userDTO);
        } catch (Exception e) {
            // 异常处理，记录错误日志并返回失败结果
            log.error("UserController.getUserInfo.error：{}", e.getMessage(), e);
            return Result.fail("个人信息查询失败！");
        }
    }

    @RequestMapping("logOut")
    public Result logOut(String userName) {
        try {
            // 记录日志
            log.info("UserController.logOut.dto:{}",userName);
            // 校验输入参数
            Preconditions.checkArgument(StringUtils.isNotBlank(userName), "用户名称不能为空！");
            StpUtil.logout(userName);
            return Result.ok();
        } catch (Exception e) {
            // 异常处理，记录错误日志并返回失败结果
            log.error("UserController.logOut.error：{}", e.getMessage(), e);
            return Result.fail("用户登出失败！");
        }
    }



    // 测试登录，浏览器访问： http://localhost:3011/user/doLogin?username=zhang&password=123456
    @RequestMapping("doLogin")
    public Result<SaTokenInfo> doLogin(@RequestParam("validCode") String validCode) {
        try {
            Preconditions.checkArgument(StringUtils.isNotBlank(validCode),"验证码不能为空！");
            SaTokenInfo tokenInfo = authUserDomainService.doLogin(validCode);
            if(tokenInfo == null) {
                return Result.fail("验证码错误");
            }
            return Result.ok(tokenInfo);
        } catch (Exception e) {
            // 异常处理，记录错误日志并返回失败结果
            log.error("UserController.doLogin.error：{}", e.getMessage(), e);
            return Result.fail("用户登录失败！");
        }
    }

    // 查询登录状态，浏览器访问： http://localhost:3011/user/isLogin
    @RequestMapping("isLogin")
    public String isLogin() {
        return "当前会话是否登录：" + StpUtil.isLogin();
    }

}
